﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Crank.Core
{
    public class Sql2005CreateScripter : Sql2005Scripter, IScripter
    {
        #region IScripter Members

        public void Script(DataModel model, TextWriter output)
        {
            ScriptEntities(model, output);
            ScriptLinks(model, output);
        }

        private void ScriptEntities(DataModel model, TextWriter output)
        {
            foreach (var entity in model.Entities.Values)
            {
                output.WriteLine("CREATE TABLE [{0}] (", entity.Name);

                output.Write(Enumerables.Join(from att in entity.Attributes
                                              select ScriptAttribute(att), ",\n"));
                output.WriteLine(",\n  CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED\n  (", entity.Name);

                output.WriteLine("    {0} ASC", Enumerables.Join(from att in entity.Keys
                                                                 select String.Format("[{0}]", att.Name), " ASC,"));
                output.WriteLine("  )\n)\nGO\n");
            }
        }

        private string ScriptAttribute(AttributeDef att)
        {
            return String.Format("  [{0}] {1}{2}{3} NULL",
                att.Name, att.Type, att.IsAuto ? " IDENTITY(1,1)" : "", att.IsRequired ? " NOT" : "");
        }



        private void ScriptLinks(DataModel model, TextWriter output)
        {
            foreach (var link in model.Links)
            {
                output.WriteLine(
                    "ALTER TABLE [{0}] WITH CHECK ADD CONSTRAINT [{2}] FOREIGN KEY ({3}) REFERENCES [{1}] ({4})\nGO\n",
                    link.LHS.Name,
                    link.RHS.Name,
                    ForeignKeyName(link),
                    Enumerables.Join(link.SourceColumns, ", "),
                    Enumerables.Join(from key in link.RHS.Keys
                                     select key.Name, ", "));
            }
        }

        #endregion
    }
}
